package com.oig.sys.auth.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.oig.common.exception.BadRequestException;
import com.oig.sys.auth.dao.ITbDepartUserDao;
import com.oig.sys.auth.dao.ITbDepartmentDao;
import com.oig.sys.auth.dao.ITbUserDao;
import com.oig.sys.auth.dto.DepartmentDto;
import com.oig.sys.auth.dto.UserMiniDto;
import com.oig.sys.auth.entity.TbDepartUser;
import com.oig.sys.auth.entity.TbUser;
import com.oig.sys.auth.service.ITbDepartUserService;
import com.oig.sys.auth.vo.DepartmentVo;
import com.oig.sys.auth.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wuxl
 */
@Service
public class TbDepartUserServiceImpl implements ITbDepartUserService {

	private final ITbDepartUserDao tbDepartUserDao;
	private final ITbUserDao userDao;
	private final ITbDepartmentDao departmentDao;

	@Autowired
	public TbDepartUserServiceImpl( ITbDepartUserDao tbDepartUserDao,ITbUserDao userDao,ITbDepartmentDao departmentDao){
		 this.tbDepartUserDao = tbDepartUserDao;
		 this.userDao = userDao;
		 this.departmentDao = departmentDao;
	}

	@Transactional
	@Override
	public List<DepartmentVo> addUserDepart(TbUser user, List<DepartmentDto> departmentDtoList) {
		List<Integer> departIdList = departmentDtoList.stream().map(DepartmentDto::getId).collect(Collectors.toList());
		List<DepartmentVo> departmentVoList = departmentDao.findAllByIds(departIdList);
		Map<Integer, DepartmentVo> departmentVoMap = departmentVoList.stream().collect(Collectors.toMap(DepartmentVo::getId, Function.identity()));
		for (DepartmentDto departmentDto : departmentDtoList){
			if (departmentDto.getId()==null){
				throw new BadRequestException("部门id为空");
			}
			DepartmentVo departmentVo = departmentVoMap.get(departmentDto.getId()) ;
			if (!departmentVo.getTenantId().equals(user.getTenantId())){
				throw new BadRequestException("部门和用户不属于同一个租户") ;
			}
			TbDepartUser departUser = new TbDepartUser();
			departUser.setDepartId(departmentDto.getId());
			departUser.setUserId(user.getId());
			departUser.setCreateTime(new Date());
			this.tbDepartUserDao.save(departUser) ;
			departIdList.add(departUser.getDepartId()) ;
		}
		return departmentVoList;
	}

	@Transactional
	@Override
	public List<DepartmentVo> updateUserDepart(TbUser user, List<DepartmentDto> departmentDtoList) {
		List<Integer> departIdList = departmentDtoList.stream().map(DepartmentDto::getId).collect(Collectors.toList());
		List<Integer> departUserList = new ArrayList<>() ;
		List<DepartmentVo> departmentVoList = departmentDao.findAllByIds(departIdList);
		Map<Integer, DepartmentVo> departmentVoMap = departmentVoList.stream().collect(Collectors.toMap(DepartmentVo::getId, Function.identity()));
		for (DepartmentDto departmentDto : departmentDtoList) {
			if (departmentDto.getId()==null){
				throw new BadRequestException("部门id为空");
			}
			TbDepartUser departUser = this.tbDepartUserDao.getByDepartIdAndUserId(departmentDto.getId(), user.getId()) ;
			if (departUser==null){
				DepartmentVo departmentVo = departmentVoMap.get(departmentDto.getId()) ;
				if (!departmentVo.getTenantId().equals(user.getTenantId())){
					throw new BadRequestException("部门和用户不属于同一个租户") ;
				}
				departUser = new TbDepartUser();
				departUser.setDepartId(departmentDto.getId());
				departUser.setUserId(user.getId());
				departUser.setCreateTime(new Date());
				this.tbDepartUserDao.save(departUser) ;
			}
			departUserList.add(departUser.getId()) ;
			departIdList.add(departmentDto.getId()) ;
		}
		//如果有索引不用这么麻烦
		List<Integer> delIdList = this.tbDepartUserDao.findAllIdByUserIdAndIdNotIn(user.getId(), departUserList);
		if (delIdList!=null &&!delIdList.isEmpty()){
			this.tbDepartUserDao.deleteByIdIn(delIdList);
		}
		return departmentDao.findAllByIds(departIdList);
	}

	@Transactional
	@Override
	public List<UserVo> addDepartUser(Integer departId, List<UserMiniDto> userDtoList) {
		List<Integer> userIdList = new ArrayList<>();
		for (UserMiniDto userDto : userDtoList){
			if (userDto.getId()==null){
				throw new BadRequestException("用户id为空");
			}
			TbDepartUser departUser = new TbDepartUser();
			departUser.setDepartId(departId);
			departUser.setUserId(userDto.getId());
			departUser.setCreateTime(new Date());
			this.tbDepartUserDao.save(departUser) ;
			userIdList.add(departUser.getUserId()) ;
		}
		List<TbUser> userList = userDao.findAllByIds(userIdList);
		return BeanUtil.copyToList(userList, UserVo.class);
	}

	@Transactional
	@Override
	public List<UserVo> updateDepartUser(Integer departId, List<UserMiniDto> userDtoList) {
		List<Integer> userIdList = new ArrayList<>();
		List<Integer> departUserList = new ArrayList<>() ;
		for (UserMiniDto userDto : userDtoList) {
			if (userDto.getId()==null){
				throw new BadRequestException("用户id为空");
			}
			TbDepartUser departUser = this.tbDepartUserDao.getByDepartIdAndUserId(departId, userDto.getId()) ;
			if (departUser==null){
				departUser = new TbDepartUser();
				departUser.setDepartId(departId);
				departUser.setUserId(userDto.getId());
				departUser.setCreateTime(new Date());
				this.tbDepartUserDao.save(departUser) ;
			}
			departUserList.add(departUser.getId()) ;
			userIdList.add(userDto.getId()) ;
		}
		//如果有索引不用这么麻烦
		List<Integer> delIdList = this.tbDepartUserDao.findAllIdByDepartIdAndIdNotIn(departId, departUserList);
		if (delIdList!=null &&!delIdList.isEmpty()){
			this.tbDepartUserDao.deleteByIdIn(delIdList);
		}
		List<TbUser> userList = userDao.findAllByIds(userIdList);
		return BeanUtil.copyToList(userList, UserVo.class);
	}

	@Transactional
	@Override
	public TbDepartUser addDepartUser(Integer departId, Integer userId) {
		TbDepartUser departUser = new TbDepartUser();
		departUser.setDepartId(departId);
		departUser.setUserId(userId);
		departUser.setCreateTime(new Date());
		this.tbDepartUserDao.save(departUser) ;
		return departUser;
	}

	@Transactional
	@Override
	public void delDepartUser(Integer departId, Integer userId) {
		if (departId!=null&&userId!=null){
			TbDepartUser departUser = this.tbDepartUserDao.getByDepartIdAndUserId(departId, userId) ;
			this.tbDepartUserDao.delete(departUser);
		} else if (departId!=null){
			List<Integer> delIdList = this.tbDepartUserDao.findAllIdByDepartId(departId) ;
			if (delIdList!=null &&!delIdList.isEmpty()){
				this.tbDepartUserDao.deleteByIdIn(delIdList);
			}
		} else {
			List<Integer> delIdList = this.tbDepartUserDao.findAllIdByUserId(userId) ;
			if (delIdList!=null &&!delIdList.isEmpty()){
				this.tbDepartUserDao.deleteByIdIn(delIdList);
			}
		}
	}


	@Override
	public List<UserVo> getDepartUser(Integer departId) {
		List<Integer> userIdList = this.tbDepartUserDao.findAllUserIdByDepartId(departId) ;
		List<TbUser> userList = userDao.findAllByIds(userIdList);
		return BeanUtil.copyToList(userList, UserVo.class);
	}


	@Override
	public List<DepartmentVo> getUserDepart(Integer userId) {
		List<Integer> departIdList = this.tbDepartUserDao.findAllDepartIdByUserId(userId) ;
		return this.departmentDao.findAllByIds(departIdList) ;
	}
}
